<?php
class DataObject extends ArrayObject
{
	/**
	 * System array, which is merging with everyobject in a constructor
	 *
	 * @var array
	 */
	public static $system = array('language'=>null);
	
	/**
	 * Array of what is need to be done safe
	 *
	 * @var array
	 */
	private $safe = array();
	
	/**
	 * DataObject providing flexibility for the logic classes.
	 * Every logic class must extend this class.
	 */
	public function __construct()
	{
		$this['system'] = (array)self::$system;
	}
	
	/**
	 * Use this function to get the valid data array
	 *
	 * @return array safe array
	 */
	public function getArrayCopy()
	{
		return $this->doSafe((array)$this);
	}
	
	/**
	 * Adding the paths to the data which needs to be special safe by tags
	 *
	 * @param string|array $path paths to the data needs to be XHTMLized
	 * @param array $tags array of tags needs to be XHTMLized
	 */
	protected function addSafe($path, $tags)
	{
		$this->safe[$path] = $tags;
	}
	
	/**
	 * Making redirect to
	 *
	 * @param string $to
	 */
	protected function redirect($to)
	{
		session_write_close();
		header('Location: '.$to);
		exit;
	}
	
	/**
	 * Returns the safe array.
	 *
	 * @todo make an optimization in XHTMLScrubber
	 * @param array $array array to make safe
	 * @return unknown
	 */
	private function doSafe($array, $path='')
	{
		foreach ($array as $k => &$v) {
			$current = $path.'/'.$k;
			
			if (is_array($v)) {
				$v = $this->doSafe($v, $current);
			} else {
				$safe = $this->isSafe($current);
				
				if (is_array($safe)) {
					$scrubber = new XHTMLScrubber($safe);
					$v = $scrubber->clean($v);
				} else if ($safe === false) {
					$v = str_replace(array('<', '>', '&', '\'', '"'), array('&lt;', '&gt;', '&amp;', '&apos;', '&quot;'), $v);
				}
				
				$v = self::repairXHTML($array[$k]);
			}
		}
		
		return $array;
	}
	
	/**
	 * Is current path in safe array?
	 *
	 * @param string $path
	 * @return array|false returns array if path was found in safe array, else false
	 */
	private function isSafe($path)
	{
		foreach ($this->safe as $k => $v) {
			if (preg_match('@^'.$k.'$@', $path)) {
				return $v;
			}
		}
		
		return false;
	}
	
	/**
	* Repairing the XML data for the outputting the real XHTML data and converting string entities to the numeric (UTF-8; same values; needed for XSLT)
	* 
	* @param string $string the data needed convert
	* @return string returns the trimmed tidied string
	*/
	public static function repairXHTML($string)
	{
		return trim(tidy_repair_string($string, array('show-body-only'=>true, 'output-xhtml'=>true, 'numeric-entities'=>true), 'utf8'));
	}
}
?>